package com.example.jbp.ddd.domain.entities;

import com.example.jbp.ddd.domain.entities.exception.FrontOptimisticLockException;
import org.hibernate.annotations.Type;
import org.springframework.data.util.ProxyUtils;

import javax.persistence.*;
import java.io.Serializable;

@MappedSuperclass
public abstract class BasicEntity<PK extends Serializable> implements HasVersion {

    @Id
    @Type(type = "uuid-char")
    private PK id;

    public PK getId() {
        return id;
    }

    protected void setId(PK id) {
        this.id = id;
    }

    @Version
    private long version;

    @Override
    public long getVersion() {
        return version;
    }

    @Override
    public void setVersion(long version) {
        if (this.version != version) {
            throw new FrontOptimisticLockException(String.format("%s ori version %d new version %d", this, this.version, version));
        }
        this.version = version;
    }

    protected BasicEntity() {

    }

    protected BasicEntity(PK id) {
        this.setId(id);
    }

    @Override
    public String toString() {
        return String.format("Entity of type %s with id: %s", this.getClass().getName(), getId());
    }

    @Override
    public boolean equals(Object obj) {

        if (null == obj) {
            return false;
        }

        if (this == obj) {
            return true;
        }

        if (!getClass().equals(ProxyUtils.getUserClass(obj))) {
            return false;
        }

        BasicEntity<?> that = (BasicEntity<?>) obj;

        return null != this.getId() && this.getId().equals(that.getId());
    }

    @Override
    public int hashCode() {

        int hashCode = 17;

        hashCode += null == getId() ? 0 : getId().hashCode() * 31;

        return hashCode;
    }
}


